package com.bcqn.service.impl;

import com.bcqn.dao.MessageMapper;
import com.bcqn.dao.PostReviewMapper;
import com.bcqn.model.Message;
import com.bcqn.model.PostReview;
import com.bcqn.model.User;
import com.bcqn.service.PostReviewService;
import com.bcqn.vo.PostReviewVo;
import com.bcqn.vo.PostReviewVos;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * PostReviewServiceImpl
 *
 * @author Kelly
 * @version v1.0
 * @date 2020/4/17 21:30
 */
@Service
public class PostReviewServiceImpl implements PostReviewService {

    private static Logger logger = LoggerFactory.getLogger(PostReviewServiceImpl.class);

    @Autowired
    private PostReviewMapper postReviewMapper;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private MessageMapper messageMapper;





    @Override
    public int update(PostReview postReview) {
        int result;
        if (postReview.getId() == null) {
            postReview.setCreateTime(new Date());
            result = postReviewMapper.insertSelective(postReview);
        } else {
            result = postReviewMapper.updateByPrimaryKeySelective(postReview);
        }
        try {
            Message record =new Message();
            record.setTriggerUserId(postReview.getUserId());
            record.setTriggeredUserId(postReview.getFatherReviewUser());
            record.setPostId(postReview.getPostId());
            record.setReviewId(postReview.getId());
            if (record.getTriggeredUserId()==null){
                //设置类型- 帖子评论为2
                record.setType("2");
            }else {
                //设置类型- 帖子回复为4
                record.setType("4");
            }
            record.setContent(postReview.getContent());
            //设置是否阅读
            record.setHaveRead("0");
            record.setCreateTime(new Date());
            messageMapper.insert(record);
        } catch (Exception e) {
            logger.error("insert Message error");
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public int delete(Long reviewId, Long userId) {
        int result =  postReviewMapper.deleteByPrimaryKey(reviewId);
        // 写日志
        return result;
    }

    @Override
    public int updateLike(Long reviewId, Long userId, Integer likeStatus) {
        // redis 存储
        //个人每次点击后总的点赞数的增加+1或者减少-1
        //利用评论和用户的id设置成唯一的键
//        Long num =  countZan(reviewId, userId,likeStatus);
//        String key = "reviewId"+reviewId+"-"+userId;
//        if (likeStatus == 1){
//            redisTemplate.boundValueOps(key).set("zan");
//        }else{
//            redisTemplate.delete(key);
//        }
//        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//        fixedThreadPool.execute(new Runnable() {
//            public void run() {
//                try {
//                    //插入消息表
//                    insertMessage(reviewId,userId);
//                    //更新总赞数
//                    postReviewMapper.updateCountLike(reviewId,num);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    logger.error("updateCountLike error");
//                }
//            }
//        });

        // 以reviewId为key查询
        String key = "REVIEWID:" + reviewId;
        String userKey = "REVIEW_USERID:"+ reviewId+"-"+userId;
        if (redisTemplate.hasKey(key)){
            Object o = redisTemplate.opsForValue().get(key);
            if (o != null) {
                try {
                    int likeNum = Integer.parseInt(o.toString());
                    if (likeStatus == 1) {
                        redisTemplate.opsForValue().set(key,likeNum + 1,10L, TimeUnit.MINUTES);
                        // 还需写入数据库review_like，查询也需要判断，看是否使用MQ
                        redisTemplate.opsForValue().set(userKey,1,1, TimeUnit.DAYS);
                        insertMessage(reviewId,userId);
                    } else {
                        redisTemplate.opsForValue().set(key,likeNum - 1,10L, TimeUnit.MINUTES);
                        redisTemplate.delete(userKey);
                    }
                } catch (NumberFormatException e) {
                    logger.error("redis value值转换失败");
                    e.printStackTrace();
                }
            }
        } else {
            // 查询数据库
            PostReview postReview = postReviewMapper.selectByPrimaryKey(reviewId);
            int likeCount = postReview.getLikeCount();
            if (likeStatus == 1) {
                redisTemplate.opsForValue().set(key,likeCount + 1,10L, TimeUnit.MINUTES);
                // 还需写入数据库review_like，查询也需要判断，看是否使用MQ
                redisTemplate.opsForValue().set(userKey,1,1, TimeUnit.DAYS);
                insertMessage(reviewId,userId);
            } else {
                if (likeCount == 0) {
                    logger.error("点赞总数为0，无法取消点赞");
                } else {
                    redisTemplate.opsForValue().set(key,likeCount - 1,10L, TimeUnit.MINUTES);
                    redisTemplate.delete(userKey);
                }
            }
        }
        return 1;
    }

//    // 统计某一条评论 总的赞数
//    public long countZan(Long reviewId,Long userId,Integer likeStatus){
//        long num = 1 ;
//        //评论的点赞总数存入redis中
//        String key ="reviewId"+reviewId;
//        //人点赞评论单独作为键值保存在redis中
//        String key1 = "reviewId"+reviewId+"-"+userId;
//        //首先判断是点赞还是取消点赞
//        if (likeStatus == 1){
//            //增加赞， 赞的总数加一
//            if (redisTemplate.hasKey(key)){
//                num = Long.valueOf(stringRedisTemplate.boundValueOps(key).get());
//                num = num+1;
//                redisTemplate.boundValueOps(key).set(Long.toString(num));
//            }else {
//                //第一次点赞设置1
//                redisTemplate.boundValueOps(key).set("1");
//            }
//            return num;
//
//        }else{
//            //取消点赞 ，赞的总数减一，先判断是否点赞过
//            if (redisTemplate.hasKey(key1)){
//                num = Long.valueOf(stringRedisTemplate.boundValueOps(key).get());
//                num = num - 1;
//                redisTemplate.boundValueOps(key).set(Long.toString(num));
//            }else {
//                //如果本身没有点赞过，那么赞的总数不变
//                num = Long.valueOf(stringRedisTemplate.boundValueOps(key).get());
//                redisTemplate.boundValueOps(key).set(Long.toString(num));
//            }
//            return num;
//        }
//    }

   /*插入信息表*/
    public void insertMessage(Long reviewId,Long userId){
        PostReview postReview = postReviewMapper.getReview(reviewId);
        Message record =new Message();
        record.setTriggerUserId(userId);
        record.setTriggeredUserId(postReview.getFatherReviewUser());
        record.setPostId(postReview.getPostId());
        record.setReviewId(postReview.getId());
        //设置类型- 帖子评论点赞为3
        record.setType("3");
        record.setContent(postReview.getContent());
        //设置是否阅读
        record.setHaveRead("0");
        record.setCreateTime(new Date());
        messageMapper.insert(record);

    }


   //根据帖子的id和类型，来分页查找评论
    @Override
    public PageInfo<PostReviewVo> getByPostId(Long postId, Long userId,Integer orderType, Integer PageNum, Integer PageSize) {

        int start = (PageNum - 1)*PageSize;
        List<PostReviewVo> postReviewList =   postReviewMapper.getByPostId(postId,orderType,start,PageSize);


        for (PostReviewVo p:postReviewList ) {
            //装本评论头像和姓名
            User user = postReviewMapper.getUserById(p.getUserId());
            p.setUserAvatar(user.getAvatar());
            p.setUserName(user.getUserName());
            p.setPosition(user.getPosition());
            //装父类评论头像和姓名
            User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
            if (user1 != null){
                p.setFatherReviewUserAvatar(user1.getAvatar());
                p.setFatherReviewUserName(user1.getUserName());
            }
            //查询子评论的总数
            Long sonReviewCount = postReviewMapper.getReviewCount(p.getOriginalReviewId());
            p.setReviewCount(sonReviewCount-1);
            String userKey = "REVIEW_USERID:"+ p.getId()+"-"+userId;
            boolean likeStatus =redisTemplate.hasKey(userKey);
            p.setLikeStatus(likeStatus);

        }
        PageInfo<PostReviewVo> postReviewPageInfo = new PageInfo<>(postReviewList);
        return postReviewPageInfo;
    }


    //根据评论id查询子评论
    @Override
    public List<PostReviewVo> getById(Long id, Long userId, int PageNum, int PageSize) {
        int start = (PageNum - 1)*PageSize;
        List<PostReviewVo> postReviewVos= postReviewMapper.getById(id, start, PageSize);
        List<PostReviewVo> postReviewVosList = new ArrayList<>();
        for (PostReviewVo p:postReviewVos ) {
            User user = postReviewMapper.getUserById(p.getUserId());
            p.setUserAvatar(user.getAvatar());
            p.setUserName(user.getUserName());
            p.setPosition(user.getPosition());
            User user1 = postReviewMapper.getUserById(p.getFatherReviewUser());
            if (user1 != null){
                p.setFatherReviewUserAvatar(user1.getAvatar());
                p.setFatherReviewUserName(user1.getUserName());
            }
            String userKey = "REVIEW_USERID:"+ p.getId()+"-"+userId;
            boolean likeStatus =redisTemplate.hasKey(userKey);
            p.setLikeStatus(likeStatus);
            if (p.getId()!=id){

                postReviewVosList.add(p);
            }

        }


        return postReviewVosList;
    }

    @Override
    public int batchUpdatePostReviewLike(Map<Long, Integer> map) {
        return postReviewMapper.batchUpdatePostReviewLike(map);
    }

}
